import wx
import sys
import os 
import cPickle
from optparse import OptionParser
from XMLCritPoints import A3DCritPoints as critXML
from xml.sax  import make_parser
#from IPython.Debugger import Tracer; debug_here = Tracer()
from CritPoint import CritPoint
import re
from browse import *

if( sys.platform == 'darwin' ):
    BIND_TEXT = True
else:
    BIND_TEXT = False
def create(parent):
    return browsewx(parent)

class browsewx(browse,wx.Frame):
    def __init__(self, *args,**kwargs):
        try:
            self.parent = args[0]
            wx.Frame.__init__(self, args[0])
            browse.__init__(self,**kwargs)

            if( self.DEBUG ): print "browsewx__init__"
            self.AllowModifyPoints = kwargs.get('AllowModifyPoints',False) 
            self.AllowAddPoints = kwargs.get('AllowAddPoints',False)
            self.AllowDeletePoints = kwargs.get('AllowDeletePoints',False)
            title = kwargs.get('title','No Title')

            self.displayAnno = True
                
            self._init_ctrls(self.parent,ttl=title,labelScheme=self.labelScheme )
            self.__doLayout()
            self.wximg = wx.EmptyImage(self.slice.shape[1],self.slice.shape[0])
            self.SetWinLevelValues()
            self.init_buffer()
            self.Show(True)
        except Exception, error:
            print "failed in browsewx.__init__", error
            sys.exit()

    def _init_coll_mnuFile_Items(self, parent, labelScheme):
        try:
            fm = parent.Append(-1, 'Open', '',wx.ITEM_NORMAL)
            self.Bind(wx.EVT_MENU,self.OnOpenFileMenu,fm)
            
            wp = parent.Append(-1,'Write PNG', '', wx.ITEM_NORMAL)
            self.Bind(wx.EVT_MENU,self.OnWritePNG,wp)

            wcp = parent.Append(-1,'Write Critical Points',
                     'Write Marked Critical Points to File',wx.ITEM_NORMAL)
            self.Bind(wx.EVT_MENU,self.OnWriteCPMenu,wcp)

            ocp = parent.Append(-1,'Open Critical Points',
                     'Open Marked Critical Points from File',wx.ITEM_NORMAL)
            self.Bind(wx.EVT_MENU,self.OnReadCPMenu,ocp)

            parent.AppendSeparator()

            for label in labelScheme:
                txtLabel = "%s (%s)"%(label,self.labelScheme.get(label,"Purple"))
                item = parent.AppendRadioItem(-1,txtLabel)
                wx.EVT_MENU(self,item.GetId(),self.setLabel)

            parent.AppendSeparator()

            toggle = parent.Append(-1,'Toggle Display\tctrl-t','',wx.ITEM_NORMAL)
            self.Bind(wx.EVT_MENU,self.ToggleDisplay,toggle)

            self.reLabel = re.compile(r"""(?P<label>[a-zA-Z ]+)[\w]*\((?P<color>[a-zA-Z ]+)\)""")
        except Exception, error:
            print "failed in _init_coll_mnuFile_Items", error
            


    def _init_coll_mnuRot_Items(self, parent):
        r0 = parent.Append(-1, 'Flip LR','',wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU,self.flipSliceUD,r0)
        
        r1 = parent.Append(-1, 'Flip TB','',wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU,self.flipSliceLR,r1)
        
        r2 = parent.Append(-1, 'Transpose','',wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU,self.transposeSlice,r2)

        r3 = parent.Append(-1, 'Flip Mask','',wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU, self.OnMnuRot_flipMask, r3)

    def _init_coll_mnuColor_Items(self, parent):
        invert = parent.Append(-1, 'Invert Colors','', wx.ITEM_NORMAL)
        self.Bind(wx.EVT_MENU, self.invertSlice, invert)

    def _init_coll_mnuScale_Items(self, parent):
        try:
            s1 = parent.Append(-1, 'Reset\tctrl-=','',wx.ITEM_NORMAL)
            self.Bind(wx.EVT_MENU, self.ResetScale, s1)
            
            s2 = parent.Append(-1, 'Decrease\tctrl-shift-i','',wx.ITEM_NORMAL)
            self.Bind(wx.EVT_MENU, self.DecreaseScale, s2)

            s3 = parent.Append(-1, 'Increase\tctrl-i','',wx.ITEM_NORMAL)
            self.Bind(wx.EVT_MENU, self.IncreaseScale, s3)
        except Exception, error:
            print "failed in _init_coll_mnuScale_Items", error
    def _init_coll_mnuView_Items(self, parent):
        xy = parent.AppendRadioItem(-1, 'XY\tctrl-z','')
        self.Bind(wx.EVT_MENU, self.SetViewXY, xy)

        xz = parent.AppendRadioItem(-1, 'XZ\tctrl-y','')
        self.Bind(wx.EVT_MENU, self.SetViewXZ, xz)
        
        yz = parent.AppendRadioItem(-1, 'YZ\tctrl-x','')
        self.Bind(wx.EVT_MENU, self.SetViewYZ, yz)

    def _init_coll_mnuProj_Items(self, parent):
        ps = parent.AppendRadioItem(-1, 'Local View\tctrl-s','')
        self.Bind(wx.EVT_MENU, self.SetSliceView, ps)

        pm = parent.AppendRadioItem(-1, 'Global View\tctrl-p','')
        self.Bind(wx.EVT_MENU, self.SetProjView, pm)

        parent.AppendSeparator()

        pmax = parent.AppendRadioItem(-1, 'maximum\tctrl-m','')
        self.Bind(wx.EVT_MENU, self.SetMaxView, pmax)

        pmin = parent.AppendRadioItem(-1, 'minimum\tctrl-shift-m','')
        self.Bind(wx.EVT_MENU, self.SetMinView, pmin)

        psum = parent.AppendRadioItem(-1, 'sumation\tctrl-u','')
        self.Bind(wx.EVT_MENU, self.SetSumView,psum)

    def _init_coll_mnuBar1_Menus(self, parent):

        parent.Append(menu=self.mnuFile, title='File')
        parent.Append(menu=self.mnuRot, title='Rotation')
        parent.Append(menu=self.mnuColor, title = 'Color')
        parent.Append(menu=self.mnuScale, title= 'Scale')
        parent.Append(menu=self.mnuView, title='View')
        parent.Append(menu=self.mnuProj, title='Proj')

    def _init_utils(self,labelScheme):
        try:
            self.mnuFile = wx.Menu(title='File')
            self._init_coll_mnuFile_Items(self.mnuFile,labelScheme)
            
            self.mnuRot = wx.Menu(title="Rotation")
            self._init_coll_mnuRot_Items(self.mnuRot)
            
            self.mnuColor = wx.Menu(title="Color")
            self._init_coll_mnuColor_Items(self.mnuColor)
            
            self.mnuScale = wx.Menu(title="Scale")
            self._init_coll_mnuScale_Items(self.mnuScale)
            
            self.mnuView = wx.Menu(title="View")
            self._init_coll_mnuView_Items(self.mnuView)
            
            self.mnuProj = wx.Menu(title="Proj")
            self._init_coll_mnuProj_Items(self.mnuProj)
            
            self.menuBar1 = wx.MenuBar()
            
            self._init_coll_mnuBar1_Menus(self.menuBar1)
        except Exception, error:
            print "failed in _init_utils",error

    def _init_ctrls(self, prnt, ttl = '',labelScheme=None):
        try:
            if( not ttl ):
                ttl = repr(self.filename)+","+self.mode+","+repr(self.slice.shape)

        
            wx.Frame.__init__(self, id=-1, name='', parent=prnt,
                  style=wx.DEFAULT_FRAME_STYLE, size=wx.Size(min(532,self.slice.shape[1]+20),min(632,self.slice.shape[0]+90)),title=ttl)
            self._init_utils(labelScheme)
            self.SetMenuBar(self.menuBar1)
            
            self.statusBar1 = wx.StatusBar(id=-1,
                  name='statusBar1', parent=self, style=0)
            
            #print "image size",self.slice.shape
            self.imageWindow = wx.ScrolledWindow(id=-1,
                  name='imageWindow', parent=self, pos=wx.Point(10, 24),
                  size=wx.Size(min(512,self.slice.shape[1]),min(512,self.slice.shape[0])))
            self.imageWindow.SetVirtualSize(self.slice.shape[1::-1])
            self.imageWindow.SetScrollRate(10,10)
            self.imageWindow.EnableScrolling(True,True)
            self.imageWindow.SetCursor(wx.STANDARD_CURSOR)
            
            wx.EVT_LEFT_UP(self.imageWindow, self.OnScrolledwindow1LeftUp)
            wx.EVT_RIGHT_UP(self.imageWindow, self.OnScrolledwindow1RightUp)

            self.Bind(wx.EVT_RIGHT_UP,self.OnScrolledwindow1RightUp,self.imageWindow)
            wx.EVT_PAINT(self.imageWindow, self.OnScrolledwindow1Paint)
            wx.EVT_SIZE(self.imageWindow, self.OnScrolledwindow1Size)
            
            # Set up Window and Level Sliders
            # set with dictionary stored values
            self.windowCtrl = wx.SpinCtrl(self,id=-1, name='windowCtrl') 
            self.windowCtrl.SetLabel('Window')
            self.Bind(wx.EVT_SPINCTRL, self.OnChangeWindow,self.windowCtrl)
            if( BIND_TEXT ):
                self.Bind(wx.EVT_TEXT, self.OnChangeWindow,self.windowCtrl)

            self.levelCtrl = wx.SpinCtrl(self,id=-1,name='levelCtrl')
            self.levelCtrl.SetLabel('Level')
            self.Bind(wx.EVT_SPINCTRL, self.OnChangeLevel,self.levelCtrl)
            if( BIND_TEXT ):
                self.Bind(wx.EVT_TEXT, self.OnChangeLevel,self.levelCtrl)
            

            self.cntrlThick = wx.SpinCtrl(self,id=-1, name='Thick')
            self.cntrlThick.SetLabel('Projection Thickness')
            self.cntrlThick.SetRange(0,100)
            self.cntrlThick.SetValue(0)
            self.Bind(wx.EVT_SPINCTRL, self.OnChangeThickness,self.cntrlThick)
            if( BIND_TEXT ):
                self.Bind(wx.EVT_TEXT, self.OnChangeThickness,self.cntrlThick)
            
            self.cntrlSlice = wx.SpinCtrl(self,id=-1, name="Slice")
            self.cntrlSlice.SetRange(0,self.nslices-1)
            self.cntrlSlice.SetValue(0)
            self.Bind(wx.EVT_SPINCTRL, self.OnChangeSlice,self.cntrlSlice)
            if( BIND_TEXT ):
                self.Bind(wx.EVT_TEXT, self.OnChangeSlice,self.cntrlSlice)            

            self.windowLabel=wx.StaticText(self, -1, ' window: ')
            self.levelLabel=wx.StaticText(self, -1, ' level: ')
            self.sliceLabel=wx.StaticText(self,-1,' slice: ')
            self.thickLabel=wx.StaticText(self,-1,' thickness: ')


        except Exception, error:
            print "failed in init_ctrls()", error

    def __doLayout(self):           
            box1 = wx.BoxSizer(wx.VERTICAL)
            box2 = wx.BoxSizer(wx.VERTICAL)
            box2.Add(self.imageWindow,1,wx.ALL|wx.EXPAND,0)
            box2.Add(self.statusBar1,0,wx.ALL|wx.EXPAND,0)
            
            
            box3 = wx.BoxSizer(wx.VERTICAL)
            box3b = wx.BoxSizer(wx.HORIZONTAL)
            box3c = wx.BoxSizer(wx.HORIZONTAL) 
            box3d = wx.BoxSizer(wx.HORIZONTAL)
            box3b.Add(self.windowLabel,0,wx.ALIGN_LEFT,0)
            box3b.Add(self.windowCtrl,0,wx.ALIGN_RIGHT,0)
            
            box3c.Add(self.levelLabel,0,wx.ALIGN_LEFT,0)
            box3c.Add(self.levelCtrl,0,wx.ALIGN_RIGHT,0)
            box3d.Add(box3b,0)
            box3d.Add(box3c,1)
            box3.Add(box3d,0)
            box3e = wx.BoxSizer(wx.HORIZONTAL)
            box3f = wx.BoxSizer(wx.HORIZONTAL) 
            box3g = wx.BoxSizer(wx.HORIZONTAL)
            box3e.Add(self.sliceLabel,0,wx.ALIGN_LEFT,0)
            box3e.Add(self.cntrlSlice,0,wx.ALIGN_RIGHT,0)
            box3f.Add(self.thickLabel,0,wx.ALIGN_LEFT,0)
            box3f.Add(self.cntrlThick,0,wx.ALIGN_RIGHT,0)
            box3g.Add(box3e,0)
            box3g.Add(box3f,1)
            box3.Add(box3g,1)
            
            box1.Add(box3, 0, wx.EXPAND)
            box1.Add(box2,1,wx.EXPAND)
            
            self.SetAutoLayout(1)
            self.SetSizer(box1)

    def GetDataFromStandardImage(self, im ):
        try:
            if( im.mode == 'L'):
                self.slice = fromstring(im.tostring(),uint8)
                self.slice.shape = im.size[::-1]
                #print "shape when Mono",self.slice.shape
                self.mode = 'L'
            elif( im.mode == 'RGB' ):
                r,g,b = im.split()
                ra = fromstring(r.tostring(),uint8)
                ra.shape = r.size[::-1]
                ga = fromstring(g.tostring(),uint8)
                ga.shape = g.size[::-1]
                ba = fromstring(b.tostring(),uint8)
                ba.shape = b.size[::-1]
                self.slice = transpose(na.array([ra,ga,ba]),axes=[1,2,0])
                #print "shape when RGB",self.slice.shape[0:2]
                self.mode = 'RGB'
            else:
                self.mode = None
                self.slice = None
        except Exception, error:
            print "failed in GetDataFromStandardImage() ", error

    def OnOpenFileMenu(self, event):
        pass


    def SetWinLevelValues(self):
        try:
            if( self.DEBUG ): print "SetWinLevelValues"
            cv = self.colorSettings[self.lproj]
            self.windowCtrl.SetRange(cv['wl'],cv['wh'])
            self.windowCtrl.SetValue(cv['wc'])
            self.levelCtrl.SetRange(cv['ll'],cv['lh'])
            self.levelCtrl.SetValue(cv['lc'])
            self.win = cv['wc']
            self.lev = cv['lc']
            print "SetWinLevelValues self.lev",self.lev
        except Exception, error:
            print "failed in SetWinLevelValues", error

    def UpdateGeometryDefinitions(self):
        try:
            nd = [self.slice.shape[1], self.slice.shape[0]]
            if( self.DEBUG ): print "UpdateGeometry slice shape",nd
            self.wximg = wx.EmptyImage(nd[0],nd[1])
        except Exception, error:
            print "failed in UpdateGeometryDefinitions()",error
            pass
    def OnChangeWindow(self, event):
        self.win = self.windowCtrl.GetValue()
        self.winlevelimage()
        self.init_buffer()

    def OnChangeLevel(self, event):
        self.lev = self.levelCtrl.GetValue()
        self.winlevelimage()
        self.init_buffer()

    def OnChangeSlice(self, event):
        try:
            # need to change this so the value updates correctly when using the
            # keyboard arrows
            self.wslice = self.cntrlSlice.GetValue()
            if( self.DEBUG ): print self.wslice
            self.SetView()
            self.winlevelimage()
            self.init_buffer()
        except Exception, error:
            print "failed in OnChangeSlice", error

    def OnChangeThickness(self, event):
        self.pt = self.cntrlThick.GetValue() # projection thickness
        self.OnChangeSlice(event)

    def OnWritePNG(self, event):
        try:
            dlg = wx.FileDialog(self, "Write to file", self.writedir, "", "PNG files (*.png)|*.png", wx.SAVE)
            if dlg.ShowModal() == wx.ID_OK:
                filename = dlg.GetPath()
            else:
                filename = 'dummy.png'
        
            self.writedir = os.path.dirname(filename)
            
            temp = wx.ImageFromBitmap(self.buffer)
            temp.SaveFile(filename,wx.BITMAP_TYPE_PNG)
        except Exception, error:
            print "failed in Write PNG", error
            event.Skip()
    def setLabel(self, event):
        """There must be a better way of doing this"""
        b = event.GetEventObject()
        items = b.GetMenuItems()
        for item in items:
            if( item.IsCheckable() and item.IsChecked() ):
                self.currentLabel = item.GetLabel()
                break
        #debug_here()
    def OnWriteCPMenu(self, event):
        """Write critical points to file"""
        try:
            dlg = wx.FileDialog(self, "Write Critical Points to file", self.writedir, "", "pckle files (*.pckle)|*.pckle|All files (*.*)|*.*", wx.SAVE)
            if dlg.ShowModal() == wx.ID_OK:
                self.pointsFile = dlg.GetPath()
            self.writeCriticalPoints() 
        except Exception, error:
            print "failed in write critical points", error
            event.Skip()
    def ToggleDisplay(self, event):
        self.displayAnno = not self.displayAnno
        self.init_buffer()

    def OnReadCPMenu(self, event):
        """read critical points from file. At this point the function reads in a
        cPickle file and extends the current critpoints attribute. No error
        checking is done regarding duplicate poitns"""
        try:
            dlg = wx.FileDialog(self, "Open Critical Points from file", self.writedir, "", "*.*", wx.OPEN)
            if dlg.ShowModal() == wx.ID_OK:
                self.pointsFile = dlg.GetPath()
            self.readCriticalPoints() 
            self.DrawCritPoints()
            self.winlevelimage()
        except Exception, error:
            print "failed in open critical points", error
            event.Skip()


    def getPoint(self,event):
        self.x, self.y = event.GetPositionTuple()
        scaling = self.scale * na.array(self.sscl)
        x0=self.imageWindow.GetViewStart()
        xs = self.imageWindow.GetScrollPixelsPerUnit()
        xx = int((self.x+x0[0]*xs[0])/scaling[0])
        yy = int((self.y+x0[1]*xs[1])/scaling[1]) #self.slice.shape[1]
        p = CritPoint()
        if( self.view == 'xy' ):
            if( self.FlipUD ):
                xx = self.mx - xx
            if( not self.FlipLR ):
                yy = self.my - yy
            zz = na.argmax(self.data[0][self.plims[0]:self.plims[1],yy,xx])+self.plims[0]
            p.extend([xx,yy,zz])
        elif( self.view == 'xz' ):
            yy = self.mz - yy
            zz = na.argmax(self.data[0][yy,self.plims[0]:self.plims[1],xx])+self.plims[0]
            p.extend([xx,zz,yy])
        else:
            yy = self.mz - yy
            zz = na.argmax(self.data[0][yy,xx,self.plims[0]:self.plims[1]])+self.plims[0]
            p.extend([zz,xx,yy])
        return p
    def OnScrolledwindow1RightUp(self, event):
        try:
            p = self.getPoint(event)
            p.setLabel(self.currentLabel)
            modified = False
            if( event.m_shiftDown and self.AllowDeletePoints ):
                if( self.DEBUG ): print "delete"
                self.delete_nearest_critpoint(p)
                modified = True
            elif( not event.m_shiftDown and self.AllowAddPoints ):
                self.critpoints.append(p)
                modified = True
            if( modified and self.critpoints ):
                self.writeCriticalPoints()
            self.DrawCritPoints()
            self.init_buffer()
        except Exception, error:
            print "failed in OnScrolledwindow1RightUp", error
    def OnScrolledwindow1LeftUp(self, event):
        try:
            p = self.getPoint(event)
            if( event.m_shiftDown and self.AllowModifyPoints ):
                self.modifyNearestCritPoint(p)
                if( self.critpoints ):
                    self.writeCriticalPoints()
                self.DrawCritPoints()
                self.init_buffer()
            else:
                print p, self.data[0][p[2],p[1],p[0]]
        except Exception, error:
            print "Failed in OnScrolledwindow1LeftUp", error

    def DrawCritPoints(self):
        try:
            if( self.DEBUG ): print "DrawCritPoints"
            if( self.view == 'xy' ):
                self.DrawCritPointsXY()
            elif( self.view == 'xz' ):
                self.DrawCritPointsXZ()
            else:
                self.DrawCritPointsYZ()
        except Exception, error:
            print "failed in DrawCritPoints", error

    def invertSlice(self, event):
        try:
            super(browsewx,self).invertSlice()
            self.init_buffer()
        except:
            event.Skip()
    def ResetScale(self, event):
        try:
            super(browsewx,self).ResetScale()
            self.init_buffer()
        except:
            event.Skip()
    def DecreaseScale(self, event):
        try:
            super(browsewx,self).DecreaseScale()
            self.init_buffer()
        except:
            event.Skip()
    def IncreaseScale(self, event):
        try:
            super(browsewx,self).IncreaseScale()
            self.init_buffer()
        except:
            event.Skip()
    def SetSliceView(self, event):
        try:
            self.viewtype = 'slice'
            self.SetView()
            self.winlevelimage()
            self.init_buffer()
        except:
            event.Skip()
    def SetProjView(self, event):
        self.viewtype = 'projection'
        self.SetView()
        self.winlevelimage()
        self.init_buffer()

    def SetMaxView(self, event):
        try:
            self.colorSettings[self.lproj]['wc'] = self.windowCtrl.GetValue()
            self.colorSettings[self.lproj]['lc'] = self.levelCtrl.GetValue()
            self.lproj = 'max'
            self.SetView()
            self.SetWinLevelValues()
            self.winlevelimage()
            self.init_buffer()
        except:
            event.Skip()
    def SetMinView(self, event):
        try:
            self.colorSettings[self.lproj]['wc'] = self.windowCtrl.GetValue()
            self.colorSettings[self.lproj]['lc'] = self.levelCtrl.GetValue()
            self.lproj = 'min'
            self.SetView()
            self.SetWinLevelValues()
            self.winlevelimage()
            self.init_buffer()
        except:
            event.Skip()
    def SetSumView(self,event):
        try:
            self.colorSettings[self.lproj]['wc'] = self.windowCtrl.GetValue()
            self.colorSettings[self.lproj]['lc'] = self.levelCtrl.GetValue()
            self.lproj = 'average'
            self.SetView()
            self.SetWinLevelValues()
            self.winlevelimage()
            self.init_buffer()
        except:
            pass
    def SetViewXY(self, event):
        try:
            super(browsewx,self).SetViewXY()
            self.cntrlSlice.SetRange(0,self.shape[0]-1)
            self.cntrlSlice.SetValue(self.wslice)
            self.UpdateGeometryDefinitions()
            self.init_buffer()
        except Exception, error:
            event.Skip()
    def SetViewXZ(self, event):
        try:
            super(browsewx,self).SetViewXZ()
            self.cntrlSlice.SetRange(0,self.shape[1]-1)
            self.cntrlSlice.SetValue(self.wslice)
            self.UpdateGeometryDefinitions()
            self.init_buffer()
        except Exception, error:
            print "failed in SetViewXZ",error
            event.Skip()
    def SetViewYZ(self, event):
        try:
            super(browsewx,self).SetViewYZ()
            self.cntrlSlice.SetRange(0,self.shape[2]-1)
            self.cntrlSlice.SetValue(self.wslice)
            self.UpdateGeometryDefinitions()
            self.init_buffer()
        except Exception, error:
            print "failed in SetViewYZ", error
            event.Skip()

    def flipSliceUD(self, event):
        try:
            super(browsewx,self).flipSliceUD()
            self.init_buffer()
        except:
            event.Skip()

    def flipSliceLR(self, event):
        try:
            super(browsewx,self).flipSliceLR()
            self.init_buffer()
        except:
            event.Skip()

    def transposeSlice(self, event):
        try:
            super(browsewx,self).transposeSlice()
            self.init_buffer()
        except:
            event.Skip()
    def OnMnuRot_flipMask(self, event):
        try:
            if( self.mode == 'L'):
                self.slice = transpose(self.slice)
            elif( self.mode == 'RGB' ):
                self.slice= transpose(self.slice,axes=[1,0,2])
            self.winlevelimage()
            self.init_buffer()
        except:
            event.Skip()
    def OnScrolledwindow1Paint(self, event):
        try:
            self.init_buffer()
        except:
            pass
 
    def OnScrolledwindow1Size(self, event):
        if( self.GetAutoLayout() ):
            self.Layout()
        else:
            event.Skip()
    def getColor(self,label):
        try:
            labelMatch = self.reLabel.match(label)
            l = labelMatch.group('label').strip()
        except:
            l = "unlabeled"

        return self.labelScheme.get(l,"red")
    def init_buffer(self):
        try:
            scaling = self.scale * na.array(self.sscl)
            w = self.wximg.GetWidth()*scaling[0]
            h = self.wximg.GetHeight()*scaling[1]
            self.imageWindow.SetVirtualSize((w,h))

            self.buffer = wx.BitmapFromImage(self.wximg.Scale(w,h))
            cdc = wx.ClientDC(self.imageWindow)
            self.imageWindow.PrepareDC(cdc)
            dc = wx.BufferedDC(cdc,self.buffer)
            if( self.DEBUG ): print "# drawwpoints",len(self.drawpoints) 
            if(len(self.drawpoints) > 0 and self.displayAnno ):
                scaling = self.scale * na.array(self.sscl)
                
                for point in self.drawpoints:
                    pen = wx.Pen(wx.NamedColour(self.getColor(point.getLabel())),1,wx.SOLID)
                    brush = wx.Brush(wx.NamedColour(self.getColor(point.getLabel())))
                    dc.SetPen(pen)
                    dc.SetBrush(brush)
                    p = [point[0],point[1],point[2]]
                    if( self.view == 'xy' ):
                        if(self.FlipLR): p[1] = self.my-p[1]
                        if(self.FlipUD): p[0] = self.mx-p[0]
                        crds = [int(p[0]*scaling[0]+0.5),int((self.my-p[1])*scaling[1]+0.5)]
                    if( self.view == 'xz' ):
                        if(self.FlipLR): p[2] = self.mz-p[2]
                        if(self.FlipUD): p[0] = self.mx-p[0]
                        crds = [int(p[0]*scaling[0]+0.5),int((self.mz-p[2])*scaling[1]+0.5)]
                    if( self.view == 'yz' ):
                        if(self.FlipLR): p[2] = self.mz-p[2]
                        if(self.FlipUD): p[1] = self.my-p[1]            
                        crds = [int(p[1]*scaling[0]+0.5),int((self.mz-p[2])*scaling[1]+0.5)]
                    sz = [max(2,int(scaling[0]+0.5)),max(2,int(scaling[1]+0.5))]
                    dc.DrawRectangle(crds[0],crds[1],sz[0],sz[1])
        
        except Exception, error:
            print "failed in init_buffer", error
def call( data = None, gFactor=[1], clp = None, mask=[],
          labelFile=None,colorFile=None, labels=None, colors = None, **args ):
    try:
        if( labels == None ):
            labels=["unlabeled","labeled"]
        if( colors == None ):
            colors=["red","green"]
        app = wx.PySimpleApp()
        wx.InitAllImageHandlers()
        if( data == None ):
            return
       
        if( labelFile ):
            labels = getLabels(labelFile)
        if( colorFile ):
            colors = getColors(colorFile)

        labelScheme = getLabelScheme(labels,colors)
        dataIn = []
        for i in range(len(data)):
            if( clp ):
                print "clipping with",clp
                dataIn.append(na.clip(data[i],clp[0],clp[1]))
            else:
                dataIn.append(data[i])

        AllowModifyPoints = args.get('AllowModifyPoints',False) 
        AllowAddPoints = args.get('AllowAddPoints',False)
        AllowDeletePoints = args.get('AllowDeletePoints',False)
        normalize = args.get('normalize',False)
        frame = browsewx(None,data=data, grayFactor = gFactor, labelScheme = labelScheme, **args)
        app.MainLoop()
    except Exception, error:
        print "failed in a3d.call()", error

if __name__ == '__main__':
    call()
